import { getDefaultOptions, urlEncodeParams, fetch } from "./core.base.js";
import { auth, server } from '../../reco.config';
import { getUID, getToken, clearToken, refreshToken } from '../func/index';
import { encode, decode } from '../../utils/base64';

export function getReferrer() {
  const rawReferrer = /\?(?:.*?&)?referrer=([^&]*).*?$/i.exec(router.location.search),
    referrer = rawReferrer && rawReferrer[1];

  return referrer ? decodeURIComponent(referrer) : "/index";
}


export function getAuthorize() {
  let token = getToken();

  if (token && (token = token.split(" ")[1])) {
    try {
      return JSON.parse(decode(token));
    } catch (ex) {

    }
  }
}

export function getLoginUrl(isLogout = false) {
  const ref = router.createHref(router.location);
  autoRefreshAnonymousToken();
  return isLogout ? "/login" : `/login?referrer=${encodeURIComponent(ref.charAt(0) === "#" ? ref.substr(1) : ref)}`;
}

let refreshPromise;
let loginPromise;



function request(input) {
  return fetch({url: input, method: 'GET'})
}

function refresh_Token() {
  const token = getAuthorize();

  return token
    ? request(`${server.url}${auth.oauth2Url}/access_token?${((token.grant_type = "refresh_token"), urlEncodeParams(token))}`, getDefaultOptions())
    : Promise.reject(authService.logoutResponse);
}



function login() {
  const uid = getUID();

  return uid ? request(`${server.url}${auth.loginUrl}/login`, getDefaultOptions({ method: "post", body: JSON.stringify({ ...server.ApiKey, ...getUID() }) })) : anonymous();
}


function anonymous() {
  return request(
    `${server.url}${auth.oauth2Url}/access_token?${urlEncodeParams({
      client_id: server.ApiKey.ApiKey,
      client_secret: server.ApiKey.Secret,
      grant_type: "client_credentials"
    })}`,
    getDefaultOptions()
  );
}

function cycle_refresh_token() {
  return refresh_Token().then(d =>
    refreshToken(!0, {
      Token: `Basic ${encode(JSON.stringify(d))}`,
      sid: d.access_token
    })
  );
}

function refreshAnonymousToken(token) {
  refreshToken(!1, {
    AnonymousToken: `Basic ${encode(JSON.stringify(token))}`,
    sid: token.access_token
  });
}

function autoRefreshAnonymousToken() {
  anonymous().then(refreshAnonymousToken);
}

setTimeout(autoRefreshAnonymousToken);

export const authService = {
  logoutResponse: { status: 403, logout: !0 },
  autoLogin: (input) => {
    loginPromise || (loginPromise = login().then(d => (d.Token && d.sid ? refreshToken(!0, d) : refreshAnonymousToken(d))));

    return new Promise((a, b) =>
      loginPromise.then(d => (input && input.headers.set("Authorization", getToken()), (loginPromise = null), a(input && fetch(input))), d => ((loginPromise = null), b(d)))
    );
  },
  refresh_token: (input) => {
    refreshPromise || (refreshPromise = cycle_refresh_token());

    return new Promise((a, b) => {
      refreshPromise.then(
        d => (input && input.headers.set("Authorization", getToken()), (loginPromise = null), a(input && fetch(input))),
        () => (
          clearToken(),
          auth.autoLogin ? authService.autoLogin(input).then(d => ((refreshPromise = null), a(d)), d => ((refreshPromise = null), b(d))) : b(authService.logoutResponse)
        )
      );
    });
  },
  cycle_refresh_token() {
    if (auth.autoRefreshToken && getToken()) {
      const date = new Date().toDateString();

      if (wx.getStorageSync("lastDate") !== date) {
        wx.setStorageSync("lastDate", date), authService.cycle_refresh_token();
      }
    }
  }
};

